import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;

public class RenameFilesMain {

    /**
     * 记录文件夹重命名时操作的文件数量
     */
    private static int fileCount = 0;
    /**
     * 记录文件夹重命名成功的文件数量
     */
    private static int succeedCount = 0;
    /**
     * 缓存文件夹重命名失败的文件名
     */
    private static final ArrayList<File> failedFiles = new ArrayList<>();

    public static void main(String[] args) {
        System.out.println("请输入文件（或文件夹）路径(exit或quit退出程序)：");
        System.out.println("带空格的路径请尽量使用英文双引号包裹如下示例：");
        System.out.println("\"E:\\Users\\pengh\\Downloads\\组件 166_1_slices\"");

        Scanner scanner = new Scanner(System.in,"UTF-8");
        File sourceFile = null;
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine().trim();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            } else if (s.isEmpty()) {
                System.out.println("请输入文件（或文件夹）路径(exit或quit退出程序)：");
                continue;
            } else if (s.startsWith("\"") && s.endsWith("\"")) {
                s = s.substring(1, s.length() - 1);
            }
            System.out.println("输入文件路径为：\n" + s);
            File file = new File(s);
            if (!file.exists()) {
                System.out.println("该文件(或文件夹)不存在，请重新输入(exit或quit退出程序)：");
                System.out.println("如果文件路径中包含符号\"–\",请将其删除或更改为\"_\")");
                continue;
            }
            if (file.isFile()) {
                sourceFile = file;
                break;
            } else if (file.isDirectory()) {
                sourceFile = file;
                break;
            } else {
                System.out.println("未知的文件类型，无法处理，请重新输入(exit或quit退出程序)：");
                break;
            }
        }
        if (sourceFile == null) {
            return;
        }
        if (sourceFile.isFile()) {
            renameFileName(sourceFile, scanner);
        } else if (sourceFile.isDirectory()) {
            renameDirectoryName(sourceFile, scanner);
        }
    }

    private static void renameDirectoryName(File file, Scanner scanner) {
        String sourceName = null;
        String targetName = null;
        System.out.println("请输入要重命名的原文件名称(需要包含文件名后缀，输入exit或quit退出程序)：");
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine().trim();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            } else if (s.isEmpty()) {
                System.out.println("请输入文件（或文件夹）路径(exit或quit退出程序)：");
            } else {
                sourceName = s;
                break;
            }
        }
        if (sourceName == null) {
            return;
        }
        System.out.println("请输入要重命名的新文件名称(需要包含文件名后缀，输入exit或quit退出程序)：");
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine().trim();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            } else if (s.isEmpty()) {
                System.out.println("请输入文件（或文件夹）路径(exit或quit退出程序)：");
            } else {
                targetName = s;
                break;
            }
        }
        if (targetName == null) {
            return;
        }
        renameFileNameInDir(file, sourceName, targetName);
        if (failedFiles.isEmpty()) {
            System.out.println("文件夹重命名完成");
            System.out.println("共找到" + fileCount + "个文件，成功重命名" + succeedCount + "个文件");
        } else {
            for (File failedFile : failedFiles) {
                System.out.println("重命名失败的文件：" + failedFile.getAbsolutePath());
            }
            System.err.println("文件夹重命名完成,部分文件重命名失败");
        }
    }

    /**
     * 将文件夹（包含子文件夹）下的指定文件名的文件重命名为目标文件名
     *
     * @param file       文件夹
     * @param sourceName 源文件名
     * @param targetName 目标文件名
     */
    private static void renameFileNameInDir(File file, String sourceName, String targetName) {
        File[] files = file.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File f : files) {
            if (f.isFile()) {
                if (f.getName().equalsIgnoreCase(sourceName)) {
                    System.out.println("找到一个文件需要重命名的：" + f.getAbsolutePath());
                    renameFileName(f, targetName);
                    fileCount++;
                }
            } else if (f.isDirectory()) {
                renameFileNameInDir(f, sourceName, targetName);
            }
        }
    }

    /**
     * 重命名文件名
     *
     * @param sourceFile 源文件
     * @param targetName 目标文件名
     */
    private static void renameFileName(File sourceFile, String targetName) {
        String sourceFilePath = sourceFile.getAbsolutePath();
        File newFile = new File(sourceFile.getParent(), targetName);
        String newFilePath = newFile.getAbsolutePath();
        if (sourceFile.renameTo(newFile)) {
            System.out.println("原文件：" + sourceFilePath + "，重命名为：" + newFilePath + " 成功！");
            succeedCount++;
        } else {
            System.out.println("原文件：" + sourceFilePath + "，重命名为：" + newFilePath + " 失败！");
            failedFiles.add(sourceFile);
        }
    }

    /**
     * 重命名文件名
     *
     * @param file    文件对象
     * @param scanner 控制台输入
     */
    private static void renameFileName(File file, Scanner scanner) {
        System.out.println("请输入新的文件名(需要包含后缀名,输入exit或quit退出程序)：");
        String newFileName = null;
        String sourceFilePath = file.getAbsolutePath();
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            } else if (s.equalsIgnoreCase(file.getName())) {
                System.out.println("新文件名与原文件名一致，请重新输入(exit或quit退出程序)：");
            } else if (s.isEmpty()) {
                System.out.println("文件名不能为空，请重新输入(exit或quit退出程序)：");
            } else {
                newFileName = s;
                break;
            }
        }
        if (newFileName == null) {
            return;
        }
        File newFile = new File(file.getParent(), newFileName);
        String newFilePath = newFile.getAbsolutePath();
        boolean success = file.renameTo(newFile);
        if (success) {
            System.out.println("原文件" + sourceFilePath + "重命名为" + newFilePath + " 成功！");
        } else {
            System.out.println("原文件" + sourceFilePath + "重命名为" + newFilePath + " 失败！");
        }
    }
}
